package demo2;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * --------神兽出没--------/
 *   ┌─┐     ┌─┐
 * ┌─┘─┴─────┘─┴─┐
 * │      ─      │
 * │  ┬─┘   └─┬  │
 * │             │
 * │      ┴      │  Code is far away from bug with the animal protecting
 * └───┐      ┌──┘  神兽保佑,代码无bug
 *     │      │
 *     │      └──────┐
 *     │             ├┐
 *     │             ┌┘
 *     └┐ ┐ ┌───┬─┐ ┌┘
 *      │ ┤ ┤   │ ┤ ┤
 *      └─┴─┘   └─┴─┘
 * --------感觉萌萌哒--------/
 *
 * @author wuyoushan
 * @date 2018/5/3
 */
public class BaseZookeeper implements Watcher {

    ZooKeeper zooKeeper;

    private static final int SESSION_TIME_OUT = 2000;

    private CountDownLatch countDownLatch = new CountDownLatch(1);

    /**
     * 连接zookeeper
     *
     * @param host host
     */
    public void connectZookeeper(String host) throws IOException,
            InterruptedException
    {
        zooKeeper = new ZooKeeper(host, SESSION_TIME_OUT, this);
        countDownLatch.await();
        System.out.println("zookeeper connect ok");
    }

    /**
     * 实现watcher的接口方法，当连接zookeeper成功后，zookeeper会通过此方法通知watcher<br>
     * 此处为如果接受到连接成功的event，则countDown，让当前线程继续其他事情。
     */
    @Override
    public void process(WatchedEvent event) {
        if (event.getState() == Event.KeeperState.SyncConnected)
        {
            System.out.println("watcher received event");
            countDownLatch.countDown();
        }
    }

    /**
     * 根据路径创建节点，并且设置节点数据
     * @param path 路径
     * @param data 数据
     */
    public String createNode(String path, byte[] data) throws KeeperException,
            InterruptedException
    {
        return this.zooKeeper.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE,
                CreateMode.PERSISTENT);
    }

    /**
     * 根据路径获取所有孩子节点
     *
     * @param path 路径
     */
    public List<String> getChildren(String path) throws KeeperException,
            InterruptedException
    {
        return this.zooKeeper.getChildren(path, false);
    }

    /**
     * 修改节点的数据
     * @param path 路径
     * @param data 数据
     * @param version 版本
     */
    public Stat setData(String path, byte [] data, int version) throws KeeperException, InterruptedException
    {
        return this.zooKeeper.setData(path, data, version);
    }

    /**
     * 判断节点是否存在，null不存在
     * @param node 节点
     */
    public Stat existsNode(String node) throws KeeperException, InterruptedException{
        return this.zooKeeper.exists(node, false);
    }

    /**
     * 根据路径获取节点数据
     *
     * @param path 路径
     */
    public byte[] getData(String path) throws KeeperException,
            InterruptedException
    {
        return this.zooKeeper.getData(path, false, null);
    }

    /**
     * 删除节点
     *
     * @param path 路径
     * @param version 版本
     */
    public void deletNode(String path, int version)
            throws InterruptedException, KeeperException
    {
        this.zooKeeper.delete(path, version);
    }

    /**
     * 关闭zookeeper连接
     */
    public void closeConnect() throws InterruptedException
    {
        if (null != zooKeeper)
        {
            zooKeeper.close();
        }
    }
}
